package com.zeus.core.config.data;

import com.zeus.common.enums.ZeusAlarmModelEnum;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 宙斯报警配置
 *
 * @author f1ybear_wang  2022/3/8 11:01 下午
 */
public interface ZeusConfig {

    /**
     * 添加监听
     * 
     * @param listener 监听接口
     * @author f1ybear_wang  2022/3/9 12:05 上午
     */
    void addListener(Listener listener);

    /**
     * 刷新
     *
     * @author f1ybear_wang  2022/5/7 14:15
     */
    void refresh();

    /**
     * 获取配置数据
     *
     * @return ConfigData 配置数据
     */
    ConfigData getConfigData();

    /**
     * 监听接口
     */
    interface Listener {

        /**
         * 更新配置
         *
         * @param configData 配置
         * @author f1ybear_wang  2022/3/9 12:05 上午
         */
        void updateConfig(ConfigData configData);
    }

    /**
     * 宙斯配置类
     */
    @Data
    class ConfigData {
        /**
         * 基础配置
         */
        protected BaseConfig baseConfig;

        /**
         * 报警级别规则
         */
        protected List<AlarmLevelRule> alarmLevelRuleList;

        /**
         * 超级配置
         */
        protected SuperConfig superConfig;

        /**
         * 规则2-阈值
         */
        protected Rule2Threshold rule2Threshold;
    }

    /**
     * 宙斯默认配置类
     */
    class DefaultConfigData extends ConfigData {
        public DefaultConfigData() {
            super();
            this.baseConfig = new BaseConfig();
            this.superConfig = new SuperConfig();
            this.rule2Threshold = new Rule2Threshold();
            this.alarmLevelRuleList = new ArrayList<>();
            this.baseConfig.setEnabled(false);
            this.superConfig.setEnabled(false);
        }
    }

    /**
     * 报警级别规则
     *
     * @author wangfeixiong126@gmail.com  2021/6/29 19:50
     */
    @Data
    class BaseConfig {

        /**
         * 报警是否开启
         */
        private Boolean enabled;

        /**
         * 报警模式，默认为NORMAL
         */
        private ZeusAlarmModelEnum model;

        /**
         * 机器人, 如果有机器人, 则不会发送给默认机器人
         */
        private List<DingTalkInfo> dingTalkList;

        /**
         * 黑名单, 可以为日志信息，类名，异常信息等(需要过滤的日志)
         */
        private Set<String> backList;

        /**
         * 错误信息字符串长度
         */
        private Integer messageLength;

        /**
         * 异常字符串长度
         */
        private Integer exceptionLength;

        /**
         * 堆栈字符串长度
         */
        private Integer stackLength;

        /**
         * ELK中索引名称
         */
        private String elkUrl;

        /**
         * 日志打印是否开启
         */
        private Boolean logPrintEnable;

        /**
         * 服务启动通知是否开启
         */
        private Boolean startNotifyEnable;

        /**
         * 服务关闭通知是否开启
         * spring.profiles.active
         */
        private Boolean shutdownNotifyEnabled;
        /**
         * 应用名称
         * spring.application.name
         */
        private String applicationName;
        /**
         * 环境
         * spring.profiles.active
         */
        private String springProfilesActive;
    }

    /**
     * 超级规则, 用于统一统计全部项目，配置不可以被覆盖！
     *
     * @author f1ybear_wang  2022/2/21 5:51 下午
     */
    @Data
    class SuperConfig {

        /**
         * 报警是否开启
         */
        private Boolean enabled;

        /**
         * 报警模式，默认为NORMAL
         */
        private ZeusAlarmModelEnum model;

        /**
         * 黑名单, 可以为日志信息，类名，异常信息等(需要过滤的日志)
         */
        private Set<String> backList;
    }

    /**
     * 报警级别规则
     *
     * @author wangfeixiong126@gmail.com  2021/6/29 19:50
     */
    @Data
    class AlarmLevelRule {
        /**
         * 报警级别，默认UN_KNOW
         */
        private String alarmLevel;

        /**
         * 机器人, 如果有机器人, 则不会发送给默认机器人
         */
        private List<DingTalkInfo> dingTalkList;

        /**
         * 包含的关键词信息
         */
        private Set<String> includeKeyWordList;

        /**
         * 报警级别速率(每分钟报警次数)
         */
        private Integer rate;

        /**
         * V2阈值
         */
        private Integer thresholdNumber;
    }

    /**
     * 钉钉机器人
     *
     * @author wangfeixiong126@gmail.com  2021/5/16 23:08
     */
    @Data
    class DingTalkInfo {
        /**
         * 凭证
         */
        private String accessToken;
        /**
         * 秘钥
         */
        private String secret;
        /**
         * 是否at全体
         */
        private Boolean atAll;

        /**
         * 被@人的手机号(在content里添加@人的手机号)
         */
        private Set<String> atMobileList;
    }

    /**
     * 规则2-阈值
     * 每个级别报警也可以单独配置阈值，从最低级开始，每升级一次，阈值会翻倍
     *
     * @author f1ybear_wang  2022/3/1 3:16 下午
     */
    @Data
    class Rule2Threshold {
        /**
         * V2阈值时间，每多少分钟内，默认为1分钟
         */
        private Integer time;

        /**
         * V2阈值
         */
        private Integer number;
    }
}
